package com.javabasic.thread.future;

import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;

/**
 * @Author xiongmin
 * @Description
 * @Date 2021-04-19 17:54
 * @Version 1.0
 **/
public class ListenableFutureTest {

    private static volatile List<String> results = new ArrayList<>();

    public static void main(String[] args) throws InterruptedException {
        testListenFuture();
    }

    public static void testListenFuture() throws InterruptedException {
        System.out.println("主线程start");
        ListeningExecutorService pool = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(5));

        Task task1 = new Task();
        task1.args = "task1";
        Task task2 = new Task();
        task2.args = "task2";
        ListenableFuture<String> future = pool.submit(task1);
        ListenableFuture<String> future2 = pool.submit(task2);
        Task task3 = new Task();
        task3.args = "task3";
        ListenableFuture<String> future3 = pool.submit(task3);

        CountDownLatch countDownLatch = new CountDownLatch(3);

        // 这个也是监听回调函数
        future2.addListener(() -> System.out.println("addListener 不能带返回值"), pool);

        /**
         * FutureCallBack接口可以对每个任务的成功或失败单独做出响应
         */
        FutureCallback<String> futureCallback = new FutureCallback<String>() {
            @Override
            public void onSuccess(String result) {
                System.out.println("Futures.addCallback 能带返回值：" + result);
                results.add(result);
                countDownLatch.countDown();
            }
            @Override
            public void onFailure(Throwable t) {
                System.out.println("出错,业务回滚或补偿");
            }
        };

        //为任务绑定回调接口
        Futures.addCallback(future, futureCallback, pool);
        // 为future2任务绑定回调接口, 该任务既有Callback又有Listener
        Futures.addCallback(future2, futureCallback, pool);
        //为任务绑定回调接口
        Futures.addCallback(future3, futureCallback, pool);

        countDownLatch.await();
        for (String result : results) {
            System.out.println(result + " ---- ");
        }
        System.out.println("主线程end");
        pool.shutdownNow();
    }
}

class Task implements Callable<String> {
    String args;
    @Override
    public String call() throws Exception {
        Thread.sleep(1000);
        System.out.println("任务：" + args);
        return "dong";
    }
}

